package araujoCoronelVillamayor.plantasVsZombies.appModelsArena

import araujoCoronelVillamayor.plantasVsZombies.domain.FactoryZombies
import araujoCoronelVillamayor.plantasVsZombies.domain.Zombie
import java.util.List
import org.uqbar.commons.utils.Observable
import araujoCoronelVillamayor.plantasVsZombies.domain.Fila
import java.util.ArrayList
import org.uqbar.commons.model.UserException
import org.uqbar.commons.model.ObservableUtils
import araujoCoronelVillamayor.plantasVsZombies.domain.AtaqueLog
import araujoCoronelVillamayor.plantasVsZombies.domain.Ataque
import java.io.Serializable

@Observable
class AtaqueAppModel implements Serializable {
	@Property List<Zombie> zombies
	@Property Zombie zombieSeleccionado
	@Property SesionAppModel sesionAppModel
	@Property List<AtaqueLog> resultadosAtaqueLog
	@Property AtaqueLog ataqueLogPaso
	@Property List<AtaqueLog> ataqueLogColeccion
	@Property Ataque ataque
	
	new(SesionAppModel sesionAppModelParametro) {
		ataqueLogColeccion = new ArrayList<AtaqueLog>
		
		sesionAppModel = sesionAppModelParametro
		
		//Deberían generarse aquí los zombies, no en el "SesionAppModel"
		//porque si se usan los mismos zombies para el almanaque,
		//una vez que son eliminados por las plantas, desaparecen
		zombies = new ArrayList<Zombie>
		val factoryZombies = FactoryZombies.getInstance
		zombies.add(factoryZombies.crearColinBlunstone())
		zombies.add(factoryZombies.crearColinBlunstone())
		zombies.add(factoryZombies.crearColinBlunstone())
		zombies.add(factoryZombies.crearCranberrie())
		zombies.add(factoryZombies.crearCranberrie())
		zombies.add(factoryZombies.crearCranberrie())
	}

//	def void evaluarResultadosAtaque(Fila fila, Zombie zombie){
//		//Si no quedan plantas en la fila entonces el zombie llegó a la meta. Pierde el jugador.
//		if(!fila.hayPlantas){
//			//Qué hacer ante el fin de juego.
//			//AtaqueFilaLog::mostrarFinalLogEnConsola(zombie)
//			ataqueLogPaso = new AtaqueLog()
//			ataqueLogPaso.generarFinalLog(zombie)
//			this.ataqueLogColeccion.add(ataqueLogPaso)
//		}
//
//		//Si murió el zombie hay que agregar recursos a la sesión.
//		if(!zombie.tieneVida){
//			zombie.entregarPremio(sesionAppModel)
//			zombies.remove(zombie)
//			
//			//AtaqueFilaLog::mostrarEntregaPremio(zombie)
//			ataqueLogPaso = new AtaqueLog()
//			ataqueLogPaso.generarEntregaPremio(zombie)
//			this.ataqueLogColeccion.add(ataqueLogPaso)
//		}
//	}

	def atacar(Fila filaAtacada, Zombie zombie){ 
		if (!(sesionAppModel.filaSeleccionada == null)){
			if (sesionAppModel.filaSeleccionadaNoVacia()){
				if (!(this.zombieSeleccionado == null)){
					if (this.zombieSeleccionado.tieneVida){
						ataque = new Ataque(zombie, filaAtacada, sesionAppModel)
						ataque.loopDeAtaque
					}
					else{
						throw new UserException(zombieSeleccionado.nombre + " está muerto.")
					}
				}
				else{
					throw new UserException("No hay un zombie seleccionado.")
				}
			}
			else{
				throw new UserException("Todas las plantas de la fila fenecieron.")
			}
		}
		else{
			throw new UserException("La fila seleccionada no existe.")
		}
	}
	
	def void refresh() {
		resultadosAtaqueLog = new ArrayList<AtaqueLog>
		resultadosAtaqueLog = ataque.coleccionDeLogs
		zombieSeleccionado = null
		ObservableUtils.firePropertyChanged(this, "zombies", this.zombies)
	}
}